package org.dxy.middleware.dynamic.thread.pool.domain.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.dxy.middleware.dynamic.thread.pool.domain.command.RefreshThreadPoolConfigCommand;
import org.dxy.middleware.dynamic.thread.pool.domain.command.RegisterThreadPoolCommand;

import java.util.concurrent.TimeUnit;


/**
 * @ description:
 * @ author: dxy
 * @ createTime: 2025/9/30 0:12
 */
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Builder
public class ThreadPoolAggregate {
    /** 应用名称 */
    private String appName;

    /** 线程池名称 */
    private String threadPoolName;

    /** 核心线程数 */
    private int corePoolSize;

    /** 最大线程数 */
    private int maximumPoolSize;

    /** 队列容量 */
    private int queueCapacity;

    /** 队列类型 */
    private String queueType;

    /** 非核心线程空闲时长数值 */
    private long keepAliveTimeValue;

    /** 非核心线程空闲时长单位 */
    private TimeUnit keepAliveTimeUnit;

    /** 核心线程是否允许超时回收 */
    private boolean allowCoreThreadTimeOut;


    public static ThreadPoolAggregate register(RegisterThreadPoolCommand command) {
        // 校验核心线程数和最大线程数
        if (command.corePoolSize() <= 0 || command.maximumPoolSize() <= 0) {
            throw new IllegalArgumentException("线程池核心数和最大线程数必须大于 0");
        }
        if (command.corePoolSize() > command.maximumPoolSize()) {
            throw new IllegalArgumentException("核心线程数不能大于最大线程数");
        }

        // 校验队列容量
        if (command.queueCapacity() <= 0) {
            throw new IllegalArgumentException("队列容量必须大于 0");
        }

        // 校验 keepAliveTime
        if (command.keepAliveTimeValue() < 0) {
            throw new IllegalArgumentException("非核心线程空闲时长必须大于等于 0");
        }
        if (command.keepAliveTimeUnit() == null) {
            throw new IllegalArgumentException("非核心线程空闲时长单位不能为空");
        }

        return ThreadPoolAggregate.builder()
                .appName(command.appName())
                .threadPoolName(command.threadPoolName())
                .corePoolSize(command.corePoolSize())
                .maximumPoolSize(command.maximumPoolSize())
                .queueCapacity(command.queueCapacity())
                .queueType(command.queueType())
                .keepAliveTimeValue(command.keepAliveTimeValue())
                .keepAliveTimeUnit(command.keepAliveTimeUnit())
                .allowCoreThreadTimeOut(command.allowCoreThreadTimeOut())
                .build();
    }

    public void refresh(RefreshThreadPoolConfigCommand command) {
        // 1. 基本合法性校验
        if (command.corePoolSize() <= 0 || command.maximumPoolSize() <= 0) {
            throw new IllegalArgumentException("线程池核心数和最大线程数必须大于 0");
        }
        if (command.corePoolSize() > command.maximumPoolSize()) {
            throw new IllegalArgumentException("核心线程数不能大于最大线程数");
        }
        if (!this.appName.equals(command.appName()) || !this.threadPoolName.equals(command.threadPoolName())) {
            throw new IllegalArgumentException("命令中的 appName 或 threadPoolName 与当前聚合不一致");
        }

        // 2. 更新聚合状态
        this.corePoolSize = command.corePoolSize();
        this.maximumPoolSize = command.maximumPoolSize();
//        this.queueCapacity = command.queueCapacity();

        // 可以选择更新修改时间，如果你想追踪的话
//        this.registerTime = LocalDateTime.now();
    }
}
